package com.yumei.trader.gym.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.PathEffect;
import android.util.AttributeSet;

import com.yumei.trader.gym.util.DensityUtils;
import com.yumei.trader.gym.view.element.StockElement;
import com.yumei.trader.gym.view.element.StockHisObject;
import com.yumei.trader.gym.view.element.TicketElement;

public abstract class KlineControlView extends KlineBaseView {

    //区间最大价格
    protected float maxPrice;
    //区间最小价格
    protected float minPrice;
    //价格缩放比例
    protected float priceZoom;
    //成交量最大值
    protected float maxShare;
    //成交量缩放比例
    protected float shareZoom;

    //最大指标值
    protected float[] maxInds = new float[8];
    //指标比例
    protected float[] indZooms = new float[8];

    //虚线参数
    protected PathEffect effects = new DashPathEffect(new float[]{3,3,3,3},1);
    protected Paint paint = new Paint();
    //趣始位始
    protected int offset = 0;
    //显示Ｋ线个数
    protected int showLen;
    //点击索引值
    protected  int curIndex = -1;
    protected boolean review = false;

    protected StockHisObject stock;
    protected StockRequest request;

    //神经元
    protected boolean neuron = false;
    //是否显示神经元最后7位信号
    protected boolean isVip = true;
    //仿真交易-下标+价位
    protected boolean drawIndex = false;
    //是否可点击
    protected boolean canClick = true;
    //预测买卖日期
    protected String startDate = "";
    protected String endDate = "";

    public KlineControlView(Context context, AttributeSet attrs) {
        super(context, attrs);
        paint.setStrokeWidth(DensityUtils.dip2px(context,1));

        reset();
    }

    protected void reset(){
        offset = 0;
        curIndex =-1;
        maxPrice=0;
        maxShare=0;
    }

    public void setOffset(int offset){
        this.offset = offset;
    }

    public int getOffset(){
        return offset;
    }

    public TicketElement getCurrent(){

        if(stock == null) return  null;

        int index = stock.tickets.size()-1-offset;
        return stock.tickets.get(index);
    }

    public void setCurIndex(int index){
        curIndex = index;
        repaint();
    }

    public void setReview(boolean review){
        this.review = review;
        repaint();
    }

    public void setCanClick(boolean canClick){
        this.canClick = canClick;
        repaint();
    }

    public StockHisObject getDataSource(){
        return stock;
    }


    public void setDataSource(StockHisObject stock, StockRequest request){

        this.stock = stock;
        this.request= request;

        checkMinAndMax();
    }

    public boolean next(){

        try {
            if (offset > 0) {
                offset--;
                return true;
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            checkMinAndMax();
            repaint();
        }
        return false;
    }

    public void setRealtime(StockElement el){

        if(stock == null || stock.tickets.size()==0) return;

        TicketElement ticketEl = stock.tickets.get(stock.tickets.size()-1);

        String date = ticketEl.date.replace("-","");
        date = date.replace("/","");

        if(date.equalsIgnoreCase(el.date)) {
            ticketEl.open = el.open;
            ticketEl.high = el.high;
            ticketEl.low = el.low;
            ticketEl.close = el.close;
            ticketEl.volume = el.volume;
        }else{
            TicketElement temp = new  TicketElement();
            temp.open = el.open;
            temp.high = el.high;
            temp.low = el.low;
            temp.close = el.close;
            temp.volume = el.volume;
            temp.date =  el.date.substring(0,4)+"/"+el.date.substring(4,6)+"/"+el.date.substring(6);
            stock.tickets.add(temp);
        }

        curIndex = -1;

        repaint();
    }

    public void setVip(boolean isVip){
        this.isVip = isVip;
    }

    public void setNeuron(boolean neuron){
        this.neuron = neuron;
        repaint();
    }

    public void setDrawIndex(boolean drawIndex){
        this.drawIndex = drawIndex;
        repaint();
    }

    public void setStartDate(String date){
        this.startDate = date;
        startDate = startDate.replace("-","/");
    }

    public void setEndDate(String date){
        this.endDate = date;
        endDate = endDate.replace("-","/");
    }

    protected  void checkMinAndMax(){

        if(stock == null){
            repaint();
            return;
        }


        int size = stock.tickets.size();

        if(size-1-offset >=0) {

            TicketElement ticket0 = stock.tickets.get(size - 1 - offset);

            maxPrice = ticket0.high;
            minPrice = ticket0.low;
            maxShare = ticket0.volume;

            for(int i=0;i<maxInds.length;i++){
                maxInds[i] = -1000;
            }

            //屏幕显示K线数量
            showLen = maxLen > (size - offset) ? (size - offset) : maxLen;

            for (int i = 0; i < showLen; i++) {

                TicketElement tick = stock.tickets.get(size - 1 - offset - i);

                maxPrice = Math.max(tick.high, maxPrice);
                minPrice = Math.min(tick.low, minPrice);
                maxShare = Math.max(tick.volume, maxShare);

                for(int j=0;j<request.indexs.length;j++){
                    int index = request.indexs[j];
                    switch(index){
                        case StockConst.Index_Down_MACD:
                            maxInds[index] = Math.max(Math.abs(tick.DIF), maxInds[index]);
                            break;
                        case StockConst.Index_Down_RSI:
                            //maxInds[index] = Math.max(Math.abs(stock.RSI[size-1-offset-i]), maxInds[index]);
                            maxInds[index] = 100;
                            break;
                        case StockConst.Index_Down_DMI:
                            //maxInds[index] = Math.max(stock.DX[size-1-offset-i], maxInds[index]);
                            maxInds[index] = 100;
                            break;
                        case StockConst.Index_Down_KDJ:
                            maxInds[index] = Math.max(tick.Jn, maxInds[index]);
                            break;
                    }
                }

            }

            priceZoom = (klineHeight - txtHeight) / (maxPrice - minPrice);
            shareZoom = (volHeight - txtHeight) / maxShare;

            for(int i=0;i<maxInds.length;i++){
                indZooms[i] = (indHeight)/maxInds[i];
            }

            repaint();
        }
    }



    protected abstract void paint(Canvas canvas);



    public synchronized void repaint(){

        Canvas canvas = holder.lockCanvas();
        if(canvas != null){
            try{
                canvas.drawColor(IColor.BG);
                drawTable(canvas);
                drawPrice(canvas);

                paint(canvas);
            }catch(Exception e){
                e.printStackTrace();
            }finally{
                holder.unlockCanvasAndPost(canvas);
            }
        }
    }



    /**
     * 画K线表格
     * @param canvas
     */

    private void drawTable(Canvas canvas){

        float cellHeight = (klineHeight-txtHeight)/5;

        paint.setColor(IColor.TABLE);
        paint.setStyle(Paint.Style.STROKE);

        //Ｋ线区
        canvas.drawRect(klineRect, paint);

        //成交量区
        canvas.drawRect(volRect, paint);

        //指标区
        canvas.drawRect(indRect, paint);

        //日期区
        canvas.drawRect(dateRect, paint);

        paint.setColor(IColor.TABLE_DASHED);
        paint.setPathEffect(effects);

        //价位等价线
        for(int i=0;i<5;i++){
            canvas.drawLine(klineRect.left+1, klineRect.top+cellHeight*i+txtHeight,
                    klineRect.right-2, klineRect.top+cellHeight*i+txtHeight, paint);
        }

       //成交量价位
        for(int i=0;i<3;i++) {
            canvas.drawLine(volRect.left + 1, volRect.bottom - i*(volHeight-txtHeight)/2,
                    volRect.right - 1, volRect.bottom - i*(volHeight-txtHeight)/2, paint);
        }

        paint.setPathEffect(null);
    }



    /**
     * 画K线价位
     * @param canvas
     */
    private void drawPrice(Canvas canvas) {

        float cha = (maxPrice - minPrice)/5.0f;
        float cellHeight = (klineHeight-txtHeight)/5;
        paint.setColor(IColor.FONT);

        //价格值
        paint.setStyle(Paint.Style.FILL);
        for(int i=0;i<5;i++){
            paint.setTextSize(FontSize12);

            String value = String.format("%.2f", maxPrice - cha*i);
            canvas.drawText(value ,klineRect.right - paint.measureText(value)-5,
                    klineRect.top+cellHeight*i+txtHeight+FontSize12, paint);
        }

        String min = String.format("%.2f", minPrice);
        canvas.drawText(min ,klineRect.right - paint.measureText(min)-5,
                klineRect.bottom-5, paint);


        paint.setColor(IColor.YELLOW);
        //成交量
        String value = String.format("%.0f", (maxShare)/100);
        canvas.drawText(value ,volRect.right - paint.measureText(value)-5,
                volRect.top+txtHeight, paint);

        canvas.drawText("x100" ,volRect.right - paint.measureText("x100")-5,
                volRect.bottom-5, paint);

    }



    protected void drawBgRect(Canvas canvas, float left, float top, float right, float bottom){
        paint.setColor(IColor.BG);
        paint.setStyle(Paint.Style.FILL);
        canvas.drawRect(left, top, right, bottom, paint);
    }
}
